import { useEffect, useRef, useState } from 'react';
import { io, Socket } from 'socket.io-client';

interface UseWebSocketOptions {
  url?: string;
  autoConnect?: boolean;
  token?: string;
}

interface WebSocketState {
  socket: Socket | null;
  isConnected: boolean;
  error: string | null;
}

export const useWebSocket = (options: UseWebSocketOptions = {}) => {
  const {
    url = 'http://localhost:3002', // 使用当前 Web 应用的端口，通过代理连接
    autoConnect = false, // 默认不自动连接，等待用户登录后再连接
    token
  } = options;

  const [state, setState] = useState<WebSocketState>({
    socket: null,
    isConnected: false,
    error: null
  });

  const socketRef = useRef<Socket | null>(null);

  useEffect(() => {
    if (!autoConnect) return;

    try {
      const socket = io(url, {
        transports: ['websocket', 'polling'],
        timeout: 5000,
        reconnection: true,
        reconnectionAttempts: 5,
        reconnectionDelay: 1000,
        auth: {
          token: token || localStorage.getItem('auth_token')
        }
      });

      socketRef.current = socket;

      socket.on('connect', () => {
        setState(prev => ({
          ...prev,
          isConnected: true,
          error: null
        }));
      });

      socket.on('disconnect', () => {
        setState(prev => ({
          ...prev,
          isConnected: false
        }));
      });

      socket.on('connect_error', (error) => {
        setState(prev => ({
          ...prev,
          isConnected: false,
          error: error.message
        }));
      });

      setState(prev => ({
        ...prev,
        socket
      }));

      return () => {
        socket.disconnect();
        socketRef.current = null;
      };
    } catch (error) {
      setState(prev => ({
        ...prev,
        error: error instanceof Error ? error.message : 'WebSocket connection failed'
      }));
    }
  }, [url, autoConnect]);

  const connect = () => {
    if (socketRef.current && !socketRef.current.connected) {
      socketRef.current.connect();
    }
  };

  const disconnect = () => {
    if (socketRef.current) {
      socketRef.current.disconnect();
    }
  };

  const emit = (event: string, data?: any) => {
    if (socketRef.current && socketRef.current.connected) {
      socketRef.current.emit(event, data);
    }
  };

  const on = (event: string, callback: (...args: any[]) => void) => {
    if (socketRef.current) {
      socketRef.current.on(event, callback);
    }
  };

  const off = (event: string, callback?: (...args: any[]) => void) => {
    if (socketRef.current) {
      socketRef.current.off(event, callback);
    }
  };

  return {
    ...state,
    connect,
    disconnect,
    emit,
    on,
    off
  };
};
